﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using LunchRoller.ViewModels;
using Microsoft.Phone.Shell;

using Microsoft.Phone.Controls;
using Microsoft.Phone.Reactive;
using ReactiveUI.Xaml;
using LunchRoller.Repositories;
using System.Collections.Specialized;
using Microsoft.Phone.Tasks;
using System.Device.Location;
using System.Net;
using System.IO;
using LunchRoller.ViewModels.Json.JiePangResponse;

// using System.Reactive.Linq;
namespace LunchRoller
{
    public class MainViewModel : ViewModelBase
    {

        public MainViewModel()
            : this(false)//For Designer
        {
            
        }

        public MainViewModel(bool running)
        {



            this.Person = new ObservableCollection<PersonModel>();
            this.Places = new ObservableCollection<PlaceModel>();
            this.Histories = new ObservableCollection<HistoryModel>();
            this.NearByPlacesJiePang = new JiePangRepository(30);
            this.geoWatcher = new GeoCoordinateWatcher(GeoPositionAccuracy.Default);


            if (running)
            {
                NotifyGeoMessage();
                var geoStateObserver = Observable.FromEvent<GeoPositionStatusChangedEventArgs>
                (eh => geoWatcher.StatusChanged += eh, eh => geoWatcher.StatusChanged -= eh);

                var geoPositionObserver = Observable.FromEvent<GeoPositionChangedEventArgs<GeoCoordinate>>
                        (eh => geoWatcher.PositionChanged += eh, eh => geoWatcher.PositionChanged -= eh);






                geoStateObserver.Subscribe(
                        s => this.GeoPositionState = s.EventArgs.Status
                    );
                geoPositionObserver.Subscribe(
                        s => this.GeoPosition = s.EventArgs.Position
                    );

                
                var selectedObservable = Observable.FromEvent< PropertyChangedEventHandler, PropertyChangedEventArgs>
                        (

                               eh =>(x, y) => eh(x, y),

                              eh =>
                              {
                                  base.PropertyChanged += eh;
                              },

                              eh =>
                              {
                                  base.PropertyChanged -= eh;
                              }
                        )
                        .Where (e=>e.EventArgs.PropertyName=="SelectedIndex")
                        ;
                //selectedObservable
                //    .Where(o => SelectedIndex == 2)
                //    .Subscribe
                //    (
                //        o =>
                //        {

                //            ChosenPerson.Clear();
                //            Person.Where(x => x.Chosen)
                //                .ToList().ForEach(x => ChosenPerson.Add(x));
                //            ChosenPlaces.Clear();
                //            Places.Where(x => x.Chosen)
                //                .ToList().ForEach(x => ChosenPlaces.Add(x));


                //        }
                //    );
                //var chosenPlacesObservable = Observable.FromEvent<NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs>
                //(
                //    eh => (x, y) => eh(x, y),
                //    eh => ChosenPlaces.CollectionChanged += eh,
                //    eh => ChosenPlaces.CollectionChanged += eh

                //);


                AddItemCommand = new ReactiveCommand(selectedObservable.Select(e => SelectedIndex == 0 || SelectedIndex == 1));
                RemoveItemCommand = new ReactiveCommand(selectedObservable.Select(e => SelectedIndex != 2));
                EditItemCommand = new ReactiveCommand(selectedObservable.Select(e => true));
                SaveAllItemsCommand = new ReactiveCommand(true.ToSingleEnumerable().ToObservable());
                SavePlaceCommand = new ReactiveCommand(true.ToSingleEnumerable().ToObservable());
                HomeCommand = new ReactiveCommand(true.ToSingleEnumerable().ToObservable());
                //DecideCommand = new ReactiveCommand(chosenPlacesObservable.Select(o => ChosenPlaces.Count > 0));
                DecideCommand = new ReactiveCommand(
                        selectedObservable.Where(e => SelectedIndex == 2).Select(o => Places.Any(p => p.Chosen))
                       );
                SMSCommand = new ReactiveCommand(true.ToSingleEnumerable().ToObservable());
                SelectAllCommand = new ReactiveCommand(true.ToSingleEnumerable().ToObservable());
                OpenIECommand = new ReactiveCommand(true.ToSingleEnumerable().ToObservable());
                GetNearbyByJiePangCommand = new ReactiveCommand(
                            geoStateObserver.Select(
                            p =>
                            {
                                //return p.EventArgs.Status == GeoPositionStatus.Ready && this.NearByPlacesJiePang.HasMore && (!IsTrial) ;
                                return p.EventArgs.Status == GeoPositionStatus.Ready && this.NearByPlacesJiePang.HasMore ;
                            }
                            )
                            .Merge
                            (
                                Observable.FromEvent< IsInvokingChangedEventArgs> ( eh=>NearByPlacesJiePang.IsInvokingChanged+=eh,eh=>NearByPlacesJiePang.IsInvokingChanged-=eh   )
                                .Select(e=>!e.EventArgs.IsInvoking)
                            )
                            
                        );

                ClearNearbyByJiePangCommand = new ReactiveCommand(true.ToSingleEnumerable().ToObservable());

                var trialObserable = Observable
                                    .FromEvent<ValueChangedEventArgs<bool>>(eh => _IsTrial.ValueChanged += eh, eh => _IsTrial.ValueChanged -= eh)
                                     .Select(e => 
                                         {
                                             return  e.EventArgs.NewValue;
                                         });



                ImportDataCommand = new ReactiveCommand(true.ToSingleEnumerable().ToObservable());// (trialObserable.Select (x=>!x));
                ExportDataCommand = new ReactiveCommand(true.ToSingleEnumerable().ToObservable());//(trialObserable.Select(x => !x));
                ImportExportCommand = new ReactiveCommand(true.ToSingleEnumerable().ToObservable());//new ReactiveCommand(true.ToSingleEnumerable().ToObservable());
                MailDataCommand = new ReactiveCommand(true.ToSingleEnumerable().ToObservable());// new ReactiveCommand(trialObserable.Select(x => !x));
                GetPaidCommand = new  ReactiveCommand(trialObserable.Select(x => x));
                SelectedIndex = 0;
                ConfigCommands();
                

           


            }



        }



        const string JIEPANG_URL = "http://api.jiepang.com/v1/locations/search?lat={0}&lon={1}&count={2}&source={3}";

        private void ConfigCommands()
        {

            ConfigAddItemCommand();
            ConfigEditItemCommand();
            ConfigSaveAllItemsCommand();
            ConfigRemoveItemCommand();
            ConfigSavePlaceCommand();
            ConfigHomeCommand();
            ConfigDecideCommand();
            ConfigSMSCommand();
            ConfigSelectAllCommand();
            ConfigOpenIECommand();
            ConfigGetNearbyByJiePangCommand();
            ConfigClearNearbyByJiePangCommand();
            ConfigImportExportCommand();
            GetPaidCommand.Subscribe
                (
                    _ =>
                    {
                        var task = new Microsoft.Phone.Tasks.MarketplaceSearchTask();

                        task.SearchTerms="Waynebaby Presents";
                        task.Show();


                    }

                );

        }

        private void ConfigImportExportCommand()
        {
            ImportExportCommand
                .Subscribe(
                    _ =>
                    {

                        //if (App.ViewModel.IsTrial)
                        //{
                        //    ImportingExportingString = "试用版本不提供导入导出功能";

                        //}
                        ((PhoneApplicationFrame)Application.Current.RootVisual).Navigate(
                        new Uri("/ImportExport.xaml", UriKind.Relative));


                    }

                );


            ExportDataCommand

                .Subscribe(
                    p =>
                    {
                        var stru = new ImportExportStruct() { Person = Person.ToArray(), Places = Places.ToArray() };
                        try
                        {


                            var ms = new MemoryStream();
                            if (string.Equals(p.ToString(), "XML", StringComparison.CurrentCultureIgnoreCase))
                            {
                                var dc = new System.Runtime.Serialization.DataContractSerializer(typeof(ImportExportStruct));

                                dc.WriteObject(ms, stru);
                            }
                            else if (string.Equals(p.ToString(), "JSON", StringComparison.CurrentCultureIgnoreCase))
                            {
                                var dc = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(ImportExportStruct));

                                dc.WriteObject(ms, stru);
                            }
                            var bu = ms.ToArray();
                            ImportingExportingString = System.Text.Encoding.UTF8.GetString(bu, 0, bu.Length);
                        }
                        catch (Exception ex)
                        {

                            if (MessageBox.Show("数据出现了一点错误，要查看详细内容么？","提示",MessageBoxButton.OKCancel)== MessageBoxResult.OK)
                            {
                                MessageBox.Show(ex.StackTrace, ex.Message, MessageBoxButton.OK);
                            }
                        }

                    }


                );
            ImportDataCommand

                .Subscribe(
                    p =>
                    {
                        ImportExportStruct stru = new ImportExportStruct();
                        try
                        {
                            var ms = new MemoryStream(Encoding.UTF8.GetBytes(ImportingExportingString));
                            if (string.Equals(p.ToString(), "XML", StringComparison.CurrentCultureIgnoreCase))
                            {
                                var dc = new System.Runtime.Serialization.DataContractSerializer(typeof(ImportExportStruct));

                                stru = (ImportExportStruct)dc.ReadObject(ms);
                            }
                            else if (string.Equals(p.ToString(), "JSON", StringComparison.CurrentCultureIgnoreCase))
                            {
                                var dc = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(ImportExportStruct));

                                stru = (ImportExportStruct)dc.ReadObject(ms);
                            }

                            this.Person.Clear();
                            stru.Person.ToList().ForEach(x => Person.Add(x));
                            this.Places.Clear();
                            stru.Places.ToList().ForEach(x => Places.Add(x));
                        }
                        catch (Exception ex)
                        {

                            if (MessageBox.Show("数据出现了一点错误，要查看详细内容么？", "提示", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
                            {
                                MessageBox.Show(ex.StackTrace, ex.Message, MessageBoxButton.OK);
                            }
                        }
                    }


                );

                MailDataCommand.Subscribe
                (
                    _ =>
                    {
                        var mt = new Microsoft.Phone.Tasks.EmailComposeTask();
                      
                        mt.Body = this.ImportingExportingString;
                        mt.Subject = "午饭吃啥数据导出" + DateTime.Now.ToString();
                        mt.Show();

                    }
                );
        }

        private void ConfigClearNearbyByJiePangCommand()
        {
            ClearNearbyByJiePangCommand.Subscribe
                (
                    o =>
                    {
                        NearByPlacesJiePang.Clear();

                    }
                );
        }

        private void ConfigGetNearbyByJiePangCommand()
        {
            GetNearbyByJiePangCommand.Subscribe
                (
                    o =>
                    {
                        this.NearByPlacesJiePang.GetNextPageAsync();
                        
                    }

                );
        }




        PropertyContainer<string> _ImportingExportingString
            = new PropertyContainer<string>("ImportingExportingString");
        public string ImportingExportingString
        {
            get { return _ImportingExportingString.Value; }
            set { _ImportingExportingString.SetValueAndTryNotify(this, value); }
        }


        



        private void ConfigOpenIECommand()
        {
            OpenIECommand.Subscribe(
                    o =>
                    {
                        var s = o as string;
                        var uri = new Uri(s);
                        if (uri.Scheme == "mailto")
                        {
                            EmailComposeTask et = new EmailComposeTask();
                            et.To = s.Split(':').Last();
                            et.Subject = "午饭吃啥"+ Setting +"反馈";
                            et.Show();


                        }
                        else
                        {
                            WebBrowserTask wbtask = new WebBrowserTask();
                            wbtask.Uri = new Uri(s);
                            wbtask.Show();
                        };
                    }
                );
        }

        private void ConfigSelectAllCommand()
        {
            SelectAllCommand
                .Where(s => SelectedIndex == 0)
                .Subscribe(
                    p =>
                    {
                        Places.ToList().ForEach(psn => psn.Chosen = true);
                    }
                );

            SelectAllCommand
                .Where(s => SelectedIndex == 1)
                .Subscribe(
                    p =>
                    {
                        Person.ToList().ForEach(psn => psn.Chosen = true);
                    }
                );
        }

        private void ConfigSMSCommand()
        {
            var command = SMSCommand;
            command.Subscribe(

                o =>
                {
                    var smst = new Microsoft.Phone.Tasks.SmsComposeTask();
                    smst.Body = string.Format("今天的午饭决定咯！ **{0}**\r\n\t发自 WP7应用 《午饭吃啥》 ", DecidedResult.Place);
                    smst.To = string.Join(";", DecidedResult.Person.Select(p => string.Format("{0}<{1}>", p.Name, p.Phone)).ToArray());
                    smst.Show();
                }

                );

        }



        private void ConfigDecideCommand()
        {
            var command = DecideCommand;
            command.Subscribe(
                    o =>
                    {
                        var r = new Random();
                        var hs = Histories.OrderByDescending(h => h.Date).Take(Setting.LatestDistinctCount).Select(h => h.Place).ToDictionary(s => s);

                        var ChosenPlaces = Places.Where(p => p.Chosen)
                            .Where(p => !hs.ContainsKey(p.Name))
                            .ToList();
                        var ChosenPerson = Person.Where(p => p.Chosen).ToList();
                        var i = r.Next(ChosenPlaces.Count);
                        var cho = ChosenPlaces[i];
                        DecidedResult = new HistoryModel()
                        {
                            Person = ChosenPerson.ToArray(),
                            Place = cho.Name,
                            Date = DateTime.Now

                        };

                        Histories.Add(DecidedResult);
                        SaveData();

                        ((PhoneApplicationFrame)Application.Current.RootVisual).Navigate(
                        new Uri("/DisplayRollResult.xaml", UriKind.Relative));

                    }

                );

        }



        PropertyContainer<HistoryModel> _DecidedResult
            = new PropertyContainer<HistoryModel>("DecidedResult");
        public HistoryModel DecidedResult
        {
            get { return _DecidedResult.Value; }
            set { _DecidedResult.SetValueAndTryNotify(this, value); }
        }





        private void ConfigRemoveItemCommand()
        {
            var command = RemoveItemCommand;
            command
                .Where(o => SelectedIndex == 0)
                .Subscribe(
                    o =>
                    {
                        var place = (PlaceModel)o;
                        Places.Remove(place);

                    }
                );
            command
                 .Where(o => SelectedIndex == 1)
                 .Subscribe(
                     o =>
                     {
                         var place = (PersonModel)o;
                         Person.Remove(place);

                     }
                );

        }

        private void ConfigSaveAllItemsCommand()
        {
            var command = SaveAllItemsCommand;
            command.Subscribe
                (
                    o =>
                    {
                        SaveData();

                    }

                );
        }

        private void ConfigSavePlaceCommand()
        {
            var command = SavePlaceCommand;
            command
                .Where(p => this.AddingOrEditingPlace.IsAdding)
                .Subscribe(
                    o =>
                    {
                        try
                        {
                            Places.Add(AddingOrEditingPlace);
                            ((PhoneApplicationFrame)Application.Current.RootVisual).GoBack();
                            SaveData();
                        }
                        catch (Exception ex)
                        {

                            MessageBox.Show(ex.Message, "出错误啦！", MessageBoxButton.OK);
                        }

                    }
                );

            command
                .Where(p => !this.AddingOrEditingPlace.IsAdding)
                .Subscribe(
                    o =>
                    {
                        try
                        {
                            //Places.Add(AddingOrEditingPlace);
                            ((PhoneApplicationFrame)Application.Current.RootVisual).GoBack();
                            SaveData();
                        }
                        catch (Exception ex)
                        {

                            MessageBox.Show(ex.Message, "出错误啦！", MessageBoxButton.OK);
                        }

                    }
                );

        }

        private void ConfigHomeCommand()
        {
            var command = HomeCommand;
            command.Subscribe(
                    o =>
                    {
                        ((PhoneApplicationFrame)Application.Current.RootVisual).GoBack();
                    }
                );

        }

        private void ConfigEditItemCommand()
        {
            var command = EditItemCommand;
            command
                .Where(o => this.SelectedIndex == 0)  //在第一屏幕的逻辑
                .Subscribe(
                new Action<object>(
                    o =>
                    {
                        this.AddingOrEditingPlace = (PlaceModel)o;
                        this.AddingOrEditingPlace.IsAdding = false;
                        ((PhoneApplicationFrame)Application.Current.RootVisual).Navigate(
                             new Uri("/AddOrEditPlace.xaml", UriKind.Relative));

                    }
                    )

                );

            //command
            //    .Where(o => this.SelectedIndex == 1)//在第二屏幕的逻辑
            //    .ObserveOn(Scheduler.CurrentThread)
            //    .Subscribe(
            //        new Action<object>(
            //            o =>
            //            {


            //            }
            //            )
            //        );

        }

        private void ConfigAddItemCommand()
        {
            IReactiveCommand command;
            command = AddItemCommand;
            command
                .Where(o => this.SelectedIndex == 0)  //在第一屏幕的逻辑
                .Subscribe(
                new Action<object>(
                    o =>
                    {
                        this.AddingOrEditingPlace = new PlaceModel() { IsAdding = true };
                        this.NearByPlacesJiePang.Clear();
                        //if (IsTrial)
                        //{
                        //    AddOrEditPlaceErrorMessage = "您正在使用试用版本，街旁搜索功能被关闭";
                        //}
                        //else 
                        if (GeoPosition != null)
                        {
                            this.NearByPlacesJiePang.Location = GeoPosition.Location;
                            AddOrEditPlaceErrorMessage = "";
                        }
                        else if (GeoPosition == null)
                        {
                            AddOrEditPlaceErrorMessage = "无法取得您当前的位置，街旁暂时不能使用";
                        }
                        
                        ((PhoneApplicationFrame)Application.Current.RootVisual).Navigate(
                             new Uri("/AddOrEditPlace.xaml", UriKind.Relative));

                    }
                    )

                );

            command
                .Where(o => this.SelectedIndex == 1)//在第二屏幕的逻辑
                .ObserveOn(Scheduler.CurrentThread)
                .Subscribe(
                    new Action<object>(
                        o =>
                        {
                            var x = new Microsoft.Phone.Tasks.PhoneNumberChooserTask();
                            x.Show();
                            x.Completed += (s, e)
                                =>
                                {
                                    if (e.Error == null)
                                    {
                                        if (e.TaskResult == Microsoft.Phone.Tasks.TaskResult.OK)
                                        {

                                            if (e.PhoneNumber == "")
                                            {

                                                MessageBox.Show("联系人选择", "您选择的联系人没有有效的电话号码", MessageBoxButton.OK);
                                            }
                                            else
                                            {
                                                var psn = new PersonModel() { Name = e.DisplayName, Chosen = true, Phone = e.PhoneNumber };
                                                Person.Add(psn);
                                                SaveData();
                                            }

                                        }
                                    }
                                };

                        }
                        )
                    );

        }



        ///// <summary>
        ///// A collection for ItemViewModel objects.
        ///// </summary>
        //public ObservableCollection<ItemViewModel> Items { get; private set; }



        PropertyContainer<ObservableCollection<PlaceModel>> _Places
            = new PropertyContainer<ObservableCollection<PlaceModel>>("Places");
        public ObservableCollection<PlaceModel> Places
        {
            get { return _Places.Value; }
            set { _Places.SetValueAndTryNotify(this, value); }
        }




        PropertyContainer<JiePangRepository> _NearByPlacesJiePang
            = new PropertyContainer<JiePangRepository>("NearByPlacesJiePang");
        public JiePangRepository NearByPlacesJiePang
        {
            get { return _NearByPlacesJiePang.Value; }
            set { _NearByPlacesJiePang.SetValueAndTryNotify(this, value); }
        }





        PropertyContainer<string> _AddOrEditPlaceErrorMessage
            = new PropertyContainer<string>("AddOrEditPlaceErrorMessage");
        public string AddOrEditPlaceErrorMessage
        {
            get { return _AddOrEditPlaceErrorMessage.Value; }
            set { _AddOrEditPlaceErrorMessage.SetValueAndTryNotify(this, value); }
        }


        


        PropertyContainer<ObservableCollection<PersonModel>> _Person
            = new PropertyContainer<ObservableCollection<PersonModel>>("Person");
        public ObservableCollection<PersonModel> Person
        {
            get { return _Person.Value; }
            set { _Person.SetValueAndTryNotify(this, value); }
        }




        //PropertyContainer<ObservableCollection<PersonModel>>  _ChosenPerson
        //    = new PropertyContainer<ObservableCollection<PersonModel>> ("ChosenPerson" ,new ObservableCollection<PersonModel >());
        //public ObservableCollection<PersonModel>  ChosenPerson
        //{
        //    get { return _ChosenPerson.Value; }
        //    set { _ChosenPerson.SetValueAndTryNotify(this, value); }
        //}





        //PropertyContainer<ObservableCollection<PlaceModel>> _ChosenPlaces
        //    = new PropertyContainer<ObservableCollection<PlaceModel>>("ChosenPlaces",new  ObservableCollection<PlaceModel>());
        //public ObservableCollection<PlaceModel> ChosenPlaces
        //{
        //    get { return _ChosenPlaces.Value; }
        //    set { _ChosenPlaces.SetValueAndTryNotify(this, value); }
        //}




        PropertyContainer<ObservableCollection<HistoryModel>> _Histories
            = new PropertyContainer<ObservableCollection<HistoryModel>>("Histories");
        public ObservableCollection<HistoryModel> Histories
        {
            get { return _Histories.Value; }
            set { _Histories.SetValueAndTryNotify(this, value); }
        }


        public FileRepository<SystemSettingModel> Settings{get;set;}



        public SystemSettingModel Setting { get { return Settings.Single(); } }


        public bool IsDataLoaded
        {
            get;
            private set;
        }

        /// <summary>
        /// Creates and adds a few ItemViewModel objects into the Items collection.
        /// </summary>
        public void LoadData()
        {

            Settings = Repositories.Repository<SystemSettingModel>.CreateJson("\\LunchRoller\\Settings.dat");

            var placesrp = Repositories.Repository<PlaceModel>.CreateJsonArray("\\LunchRoller\\Places.dat");
            Places = placesrp;

            if (Places.Count == 0)
            {
                App.SampleData.Places.ForEach(x => Places.Add(x)).ToArray();

            }


            var personrp = Repositories.Repository<PersonModel>.CreateJsonArray("\\LunchRoller\\Person.dat");
            Person = personrp;

            if (Person.Count == 0)
            {
                App.SampleData.Person.ForEach(x => Person.Add(x)).ToArray();

            }




            var placeshis = Repositories.Repository<HistoryModel>.CreateJsonArray("\\LunchRoller\\History.dat");
            Histories = placeshis;


            // Sample data; replace with real data
            //this.Items.Add(new ItemViewModel() { LineOne = "runtime one", LineTwo = "Maecenas praesent accumsan bibendum", LineThree = "Facilisi faucibus habitant inceptos interdum lobortis nascetur pharetra placerat pulvinar sagittis senectus sociosqu" });
            //this.Items.Add(new ItemViewModel() { LineOne = "runtime two", LineTwo = "Dictumst eleifend facilisi faucibus", LineThree = "Suscipit torquent ultrices vehicula volutpat maecenas praesent accumsan bibendum dictumst eleifend facilisi faucibus" });
            //this.Items.Add(new ItemViewModel() { LineOne = "runtime three", LineTwo = "Habitant inceptos interdum lobortis", LineThree = "Habitant inceptos interdum lobortis nascetur pharetra placerat pulvinar sagittis senectus sociosqu suscipit torquent" });
            //this.Items.Add(new ItemViewModel() { LineOne = "runtime four", LineTwo = "Nascetur pharetra placerat pulvinar", LineThree = "Ultrices vehicula volutpat maecenas praesent accumsan bibendum dictumst eleifend facilisi faucibus habitant inceptos" });
            //this.Items.Add(new ItemViewModel() { LineOne = "runtime five", LineTwo = "Maecenas praesent accumsan bibendum", LineThree = "Maecenas praesent accumsan bibendum dictumst eleifend facilisi faucibus habitant inceptos interdum lobortis nascetur" });
            //this.Items.Add(new ItemViewModel() { LineOne = "runtime six", LineTwo = "Dictumst eleifend facilisi faucibus", LineThree = "Pharetra placerat pulvinar sagittis senectus sociosqu suscipit torquent ultrices vehicula volutpat maecenas praesent" });
            //this.Items.Add(new ItemViewModel() { LineOne = "runtime seven", LineTwo = "Habitant inceptos interdum lobortis", LineThree = "Accumsan bibendum dictumst eleifend facilisi faucibus habitant inceptos interdum lobortis nascetur pharetra placerat" });
            //this.Items.Add(new ItemViewModel() { LineOne = "runtime eight", LineTwo = "Nascetur pharetra placerat pulvinar", LineThree = "Pulvinar sagittis senectus sociosqu suscipit torquent ultrices vehicula volutpat maecenas praesent accumsan bibendum" });
            //this.Items.Add(new ItemViewModel() { LineOne = "runtime nine", LineTwo = "Maecenas praesent accumsan bibendum", LineThree = "Facilisi faucibus habitant inceptos interdum lobortis nascetur pharetra placerat pulvinar sagittis senectus sociosqu" });
            //this.Items.Add(new ItemViewModel() { LineOne = "runtime ten", LineTwo = "Dictumst eleifend facilisi faucibus", LineThree = "Suscipit torquent ultrices vehicula volutpat maecenas praesent accumsan bibendum dictumst eleifend facilisi faucibus" });
            //this.Items.Add(new ItemViewModel() { LineOne = "runtime eleven", LineTwo = "Habitant inceptos interdum lobortis", LineThree = "Habitant inceptos interdum lobortis nascetur pharetra placerat pulvinar sagittis senectus sociosqu suscipit torquent" });
            //this.Items.Add(new ItemViewModel() { LineOne = "runtime twelve", LineTwo = "Nascetur pharetra placerat pulvinar", LineThree = "Ultrices vehicula volutpat maecenas praesent accumsan bibendum dictumst eleifend facilisi faucibus habitant inceptos" });
            //this.Items.Add(new ItemViewModel() { LineOne = "runtime thirteen", LineTwo = "Maecenas praesent accumsan bibendum", LineThree = "Maecenas praesent accumsan bibendum dictumst eleifend facilisi faucibus habitant inceptos interdum lobortis nascetur" });
            //this.Items.Add(new ItemViewModel() { LineOne = "runtime fourteen", LineTwo = "Dictumst eleifend facilisi faucibus", LineThree = "Pharetra placerat pulvinar sagittis senectus sociosqu suscipit torquent ultrices vehicula volutpat maecenas praesent" });
            //this.Items.Add(new ItemViewModel() { LineOne = "runtime fifteen", LineTwo = "Habitant inceptos interdum lobortis", LineThree = "Accumsan bibendum dictumst eleifend facilisi faucibus habitant inceptos interdum lobortis nascetur pharetra placerat" });
            //this.Items.Add(new ItemViewModel() { LineOne = "runtime sixteen", LineTwo = "Nascetur pharetra placerat pulvinar", LineThree = "Pulvinar sagittis senectus sociosqu suscipit torquent ultrices vehicula volutpat maecenas praesent accumsan bibendum" });

            this.IsDataLoaded = true;
        }
        public void SaveData()
        {
            ((FileRepository<PersonModel>)Person).SaveAll();
            ((FileRepository<PlaceModel>)Places).SaveAll();
            ((FileRepository<HistoryModel>)Histories).SaveAll();
            Settings.SaveAll();
            //var personrp = Repositories.Repository<string, PersonModel>.CreateXml(x => x.Name, "\\LunchRoller\\Person.dat");

            //personrp.SaveAll();


            //var placesrp = Repositories.Repository<string, PlaceModel>.CreateXml(x => x.Name, "\\LunchRoller\\Places.dat");
            //placesrp.SaveAll();


            //var placeshis = Repositories.Repository<DateTime, HistoryModel>.CreateXml(x => x.Date, "\\LunchRoller\\History.dat");
            //placeshis.ForEach(p => this.Histories.Add(p));


            // Sample data; replace with real data
            //this.Items.Add(new ItemViewModel() { LineOne = "runtime one", LineTwo = "Maecenas praesent accumsan bibendum", LineThree = "Facilisi faucibus habitant inceptos interdum lobortis nascetur pharetra placerat pulvinar sagittis senectus sociosqu" });
            //this.Items.Add(new ItemViewModel() { LineOne = "runtime two", LineTwo = "Dictumst eleifend facilisi faucibus", LineThree = "Suscipit torquent ultrices vehicula volutpat maecenas praesent accumsan bibendum dictumst eleifend facilisi faucibus" });
            //this.Items.Add(new ItemViewModel() { LineOne = "runtime three", LineTwo = "Habitant inceptos interdum lobortis", LineThree = "Habitant inceptos interdum lobortis nascetur pharetra placerat pulvinar sagittis senectus sociosqu suscipit torquent" });
            //this.Items.Add(new ItemViewModel() { LineOne = "runtime four", LineTwo = "Nascetur pharetra placerat pulvinar", LineThree = "Ultrices vehicula volutpat maecenas praesent accumsan bibendum dictumst eleifend facilisi faucibus habitant inceptos" });
            //this.Items.Add(new ItemViewModel() { LineOne = "runtime five", LineTwo = "Maecenas praesent accumsan bibendum", LineThree = "Maecenas praesent accumsan bibendum dictumst eleifend facilisi faucibus habitant inceptos interdum lobortis nascetur" });
            //this.Items.Add(new ItemViewModel() { LineOne = "runtime six", LineTwo = "Dictumst eleifend facilisi faucibus", LineThree = "Pharetra placerat pulvinar sagittis senectus sociosqu suscipit torquent ultrices vehicula volutpat maecenas praesent" });
            //this.Items.Add(new ItemViewModel() { LineOne = "runtime seven", LineTwo = "Habitant inceptos interdum lobortis", LineThree = "Accumsan bibendum dictumst eleifend facilisi faucibus habitant inceptos interdum lobortis nascetur pharetra placerat" });
            //this.Items.Add(new ItemViewModel() { LineOne = "runtime eight", LineTwo = "Nascetur pharetra placerat pulvinar", LineThree = "Pulvinar sagittis senectus sociosqu suscipit torquent ultrices vehicula volutpat maecenas praesent accumsan bibendum" });
            //this.Items.Add(new ItemViewModel() { LineOne = "runtime nine", LineTwo = "Maecenas praesent accumsan bibendum", LineThree = "Facilisi faucibus habitant inceptos interdum lobortis nascetur pharetra placerat pulvinar sagittis senectus sociosqu" });
            //this.Items.Add(new ItemViewModel() { LineOne = "runtime ten", LineTwo = "Dictumst eleifend facilisi faucibus", LineThree = "Suscipit torquent ultrices vehicula volutpat maecenas praesent accumsan bibendum dictumst eleifend facilisi faucibus" });
            //this.Items.Add(new ItemViewModel() { LineOne = "runtime eleven", LineTwo = "Habitant inceptos interdum lobortis", LineThree = "Habitant inceptos interdum lobortis nascetur pharetra placerat pulvinar sagittis senectus sociosqu suscipit torquent" });
            //this.Items.Add(new ItemViewModel() { LineOne = "runtime twelve", LineTwo = "Nascetur pharetra placerat pulvinar", LineThree = "Ultrices vehicula volutpat maecenas praesent accumsan bibendum dictumst eleifend facilisi faucibus habitant inceptos" });
            //this.Items.Add(new ItemViewModel() { LineOne = "runtime thirteen", LineTwo = "Maecenas praesent accumsan bibendum", LineThree = "Maecenas praesent accumsan bibendum dictumst eleifend facilisi faucibus habitant inceptos interdum lobortis nascetur" });
            //this.Items.Add(new ItemViewModel() { LineOne = "runtime fourteen", LineTwo = "Dictumst eleifend facilisi faucibus", LineThree = "Pharetra placerat pulvinar sagittis senectus sociosqu suscipit torquent ultrices vehicula volutpat maecenas praesent" });
            //this.Items.Add(new ItemViewModel() { LineOne = "runtime fifteen", LineTwo = "Habitant inceptos interdum lobortis", LineThree = "Accumsan bibendum dictumst eleifend facilisi faucibus habitant inceptos interdum lobortis nascetur pharetra placerat" });
            //this.Items.Add(new ItemViewModel() { LineOne = "runtime sixteen", LineTwo = "Nascetur pharetra placerat pulvinar", LineThree = "Pulvinar sagittis senectus sociosqu suscipit torquent ultrices vehicula volutpat maecenas praesent accumsan bibendum" });

            this.IsDataLoaded = true;
        }



 

        

        PropertyContainer<PlaceModel> _AddingOrEditingPlace
            = new PropertyContainer<PlaceModel>("AddingOrEditingPlace");
        public PlaceModel AddingOrEditingPlace
        {
            get { return _AddingOrEditingPlace.Value; }
            set { _AddingOrEditingPlace.SetValueAndTryNotify(this, value); }
        }









        internal int _SelectedIndex
            = -1;
        public int SelectedIndex
        {
            get { return _SelectedIndex; }
            set { 
                _SelectedIndex= value;

                try
                {

             
                base.RaisePropertyChanged("SelectedIndex");
                }
                catch (Exception)
                {


                }
            }
        }







        PropertyContainer<bool> _IsTrial
            = new PropertyContainer<bool>("IsTrial");
        public bool IsTrial
        {
            get { return _IsTrial.Value; }
            set { _IsTrial.SetValueAndTryNotify(this, value); }
        }







        PropertyContainer<bool> _IsGeoStarted
     = new PropertyContainer<bool>("IsGeoStarted");
        public bool IsGeoStarted
        {
            get { return _IsGeoStarted.Value; }
            set
            {
                
                if (value)
                {

                    geoWatcher.Start();
                }
                else
                {
                    geoWatcher.Stop();

                }
                _IsGeoStarted.SetValueAndTryNotify(this, value);
                NotifyGeoMessage();
            }
        }


        PropertyContainer<GeoPosition<GeoCoordinate>> _GeoPosition
            = new PropertyContainer<GeoPosition<GeoCoordinate>>("GeoPosition");
        public GeoPosition<GeoCoordinate> GeoPosition
        {
            get { return _GeoPosition.Value; }
            set { _GeoPosition.SetValueAndTryNotify(this, value); }
        }



        PropertyContainer<GeoPositionStatus> _GeoPositionState
            = new PropertyContainer<GeoPositionStatus>("GeoPositionState");
        public GeoPositionStatus GeoPositionState
        {
            get { return _GeoPositionState.Value; }
            set
            {
                _GeoPositionState.SetValueAndTryNotify(this, value);
                NotifyGeoMessage();
            }
        }

        private void NotifyGeoMessage()
        {
            _GeoPositionStateMessage.SetValueAndTryNotify(this, "地理服务状态: " + (IsGeoStarted ? "启用, " : "禁用, ") + GeoPositionState.ToString());
        }




        PropertyContainer<string> _GeoPositionStateMessage
            = new PropertyContainer<string>("GeoPositionStateMessage");
        public string GeoPositionStateMessage
        {
            get { return _GeoPositionStateMessage.Value; }

        }







        private GeoCoordinateWatcher geoWatcher;

        public IReactiveCommand AddItemCommand { get; private set; }
        public IReactiveCommand RemoveItemCommand { get; private set; }
        public IReactiveCommand EditItemCommand { get; private set; }
        public IReactiveCommand SaveAllItemsCommand { get; private set; }
        public IReactiveCommand SavePlaceCommand { get; private set; }
        public IReactiveCommand HomeCommand { get; private set; }
        public IReactiveCommand DecideCommand { get; private set; }
        public IReactiveCommand SMSCommand { get; private set; }
        public IReactiveCommand SelectAllCommand { get; private set; }
        public IReactiveCommand OpenIECommand { get; private set; }
        public IReactiveCommand GetNearbyByJiePangCommand { get; private set; }
        public IReactiveCommand ClearNearbyByJiePangCommand { get; private set; }

        public IReactiveCommand ImportExportCommand { get; private set; }
        public IReactiveCommand MailDataCommand { get; private set; }
        public IReactiveCommand ImportDataCommand { get; private set; }
        public IReactiveCommand ExportDataCommand { get; private set; }
        public IReactiveCommand GetPaidCommand{ get; private set; }


    }
}